<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>JavaScript作用域和作用域链 | dmf的个人博客</title><meta name="author" content="dmf"><meta name="copyright" content="dmf"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="描述">
<meta property="og:type" content="article">
<meta property="og:title" content="JavaScript作用域和作用域链">
<meta property="og:url" content="https://gitee.com/dmf-c/blog/2021/07/10/js_file/ScopeChain/index.html">
<meta property="og:site_name" content="dmf的个人博客">
<meta property="og:description" content="描述">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://img1.baidu.com/it/u=3691791879,443411760&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889">
<meta property="article:published_time" content="2021-07-09T16:00:00.000Z">
<meta property="article:modified_time" content="2022-10-12T07:32:05.771Z">
<meta property="article:author" content="dmf">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://img1.baidu.com/it/u=3691791879,443411760&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889"><link rel="shortcut icon" href="/blog/img/favicon.png"><link rel="canonical" href="https://gitee.com/dmf-c/blog/2021/07/10/js_file/ScopeChain/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/blog/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/blog/',
  algolia: undefined,
  localSearch: undefined,
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'JavaScript作用域和作用域链',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-10-12 15:32:05'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><meta name="generator" content="Hexo 6.3.0"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/blog/archives/"><div class="headline">文章</div><div class="length-num">27</div></a><a href="/blog/tags/"><div class="headline">标签</div><div class="length-num">0</div></a><a href="/blog/categories/"><div class="headline">分类</div><div class="length-num">6</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/blog/"><i class="fa-fw iconfont icon-shouyex"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-zuixinwenzhang_huaban"></i><span> 找文章</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/blog/categories/"><i class="fa-fw iconfont icon-fenlei1"></i><span> 分类</span></a></li><li><a class="site-page child" href="/blog/tags/"><i class="fa-fw iconfont icon-biaoqian1"></i><span> 标签</span></a></li><li><a class="site-page child" href="/blog/archives/"><i class="fa-fw iconfont icon-shijianzhou"></i><span> 归档</span></a></li></ul></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://img1.baidu.com/it/u=3691791879,443411760&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=500&amp;h=889')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/blog/">dmf的个人博客</a></span><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page" href="/blog/"><i class="fa-fw iconfont icon-shouyex"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-zuixinwenzhang_huaban"></i><span> 找文章</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/blog/categories/"><i class="fa-fw iconfont icon-fenlei1"></i><span> 分类</span></a></li><li><a class="site-page child" href="/blog/tags/"><i class="fa-fw iconfont icon-biaoqian1"></i><span> 标签</span></a></li><li><a class="site-page child" href="/blog/archives/"><i class="fa-fw iconfont icon-shijianzhou"></i><span> 归档</span></a></li></ul></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">JavaScript作用域和作用域链</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="fa-fw post-meta-icon far fa-calendar-alt"></i><span class="post-meta-label">发表于</span><time datetime="2021-07-09T16:00:00.000Z" title="发表于 2021-07-10 00:00:00">2021-07-10</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/blog/categories/Javascript/">Javascript</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="JavaScript作用域和作用域链"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h2 id="作用域-Scope"><a href="#作用域-Scope" class="headerlink" title="作用域(Scope)"></a>作用域(Scope)</h2><h3 id="什么是作用域"><a href="#什么是作用域" class="headerlink" title="什么是作用域"></a>什么是作用域</h3><p>作用域是在运行时代码中的某些特定部分中变量，函数和对象的可访问性。换句话说，作用域决定了代码区块中变量和其他资源的可见性。</p>
<pre><code>function outFun2() &#123;
    var inVariable = &quot;内层变量2&quot;;
&#125;
outFun2();//要先执行这个函数，否则根本不知道里面是啥
console.log(inVariable); // Uncaught ReferenceError: inVariable is not defined
</code></pre>
<p>变量inVariable在全局作用域没有声明，所以在全局作用域下取值会报错。可以这样理解：作用域就是一个独立的地盘，让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量，不同作用域下同名变量不会有冲突。</p>
<p>ES6 之前 JavaScript 没有块级作用域,只有全局作用域和函数作用域。ES6的到来，为我们提供了‘块级作用域’,可通过新增命令let和const来体现。</p>
<h3 id="全局作用域和函数作用域"><a href="#全局作用域和函数作用域" class="headerlink" title="全局作用域和函数作用域"></a>全局作用域和函数作用域</h3><p>在代码中任何地方都能访问到的对象拥有全局作用域，一般来说以下几种情形拥有全局作用域：</p>
<ul>
<li><p>最外层函数 和在最外层函数外面定义的变量拥有全局作用域</p>
<pre><code>  var outVariable = &quot;我是最外层变量&quot;; //最外层变量
  function outFun() &#123; //最外层函数
      var inVariable = &quot;内层变量&quot;;
      function innerFun() &#123; //内层函数
          console.log(inVariable);
      &#125;
      innerFun();
  &#125;
  console.log(outVariable); //我是最外层变量
  outFun(); //内层变量
  console.log(inVariable); //inVariable is not defined
  innerFun(); //innerFun is not defined
</code></pre>
</li>
<li><p>所有末定义直接赋值的变量自动声明为拥有全局作用域</p>
<pre><code>  function outFun2() &#123;
      variable = &quot;未定义直接赋值的变量&quot;;
      var inVariable2 = &quot;内层变量2&quot;;
  &#125;
  outFun2();//要先执行这个函数，否则根本不知道里面是啥
  console.log(variable); //未定义直接赋值的变量
  console.log(inVariable2); //inVariable2 is not defined
</code></pre>
</li>
<li><p>所有window对象的属性拥有全局作用域</p>
</li>
</ul>
<p>一般情况下，window对象的内置属性都拥有全局作用域，例如window.name、window.location、window.top等等。</p>
<p>全局作用域有个弊端：如果我们写了很多行 JS 代码，变量定义都没有用函数包括，那么它们就全部都在全局作用域中。这样就会 污染全局命名空间, 容易引起命名冲突。</p>
<pre><code>// 张三写的代码中
var data = &#123;a: 100&#125;

// 李四写的代码中
var data = &#123;x: true&#125;
</code></pre>
<p>函数作用域,是指声明在函数内部的变量，和全局作用域相反，局部作用域一般只在固定的代码片段内可访问到，最常见的例如函数内部。</p>
<pre><code>function doSomething()&#123;
    var blogName=&quot;浪里行舟&quot;;
    function innerSay()&#123;
        alert(blogName);
    &#125;
    innerSay();
&#125;
alert(blogName); //脚本错误
innerSay(); //脚本错误
</code></pre>
<p><strong>作用域是分层的，内层作用域可以访问外层作用域的变量，反之则不行。</strong></p>
<!-- 用泡泡来比喻作用域可能好理解一点 -->

<!-- 最后输出的结果为 2, 4, 12

* 泡泡1是全局作用域，有标识符foo；
* 泡泡2是作用域foo，有标识符a,bar,b；
* 泡泡3是作用域bar，仅有标识符c。 -->

<p>值得注意的是：<strong>块语句（大括号“｛｝”中间的语句），如 if 和 switch 条件语句或 for 和 while 循环语句，不像函数，它们不会创建一个新的作用域。</strong>在块语句中定义的变量将保留在它们已经存在的作用域中。</p>
<pre><code>if (true) &#123;
    // &#39;if&#39; 条件语句块不会创建一个新的作用域
    var name = &#39;Hammad&#39;; // name 依然在全局作用域中
&#125;
console.log(name); // logs &#39;Hammad&#39;
</code></pre>
<p>而如果不理解这种特有行为，就可能导致bug 。正因为如此， ES6 引入了块级作用域，让变量的生命周期更加可控。</p>
<h3 id="块级作用域"><a href="#块级作用域" class="headerlink" title="块级作用域"></a>块级作用域</h3><p>块级作用域可通过新增命令let和const声明，所声明的变量在指定块的作用域外无法被访问。块级作用域在如下情况被创建：</p>
<ol>
<li><p>在一个函数内部</p>
</li>
<li><p>在一个代码块（由一对花括号包裹）内部<br>let 声明的语法与 var 的语法一致。你基本上可以用 let 来代替 var 进行变量声明，但会将变量的作用域限制在当前代码块中。块级作用域有以下几个特点：</p>
</li>
</ol>
<ul>
<li>声明变量不会提升到代码块顶部</li>
</ul>
<p>let&#x2F;const 声明并不会被提升到当前代码块的顶部，因此你需要手动将 let&#x2F;const 声明放置到顶部，以便让变量在整个代码块内部可用。</p>
<pre><code>function getValue(condition) &#123;
if (condition) &#123;
let value = &quot;blue&quot;;
return value;
&#125; else &#123;
// value 在此处不可用
return null;
&#125;
// value 在此处不可用
&#125;
</code></pre>
<ul>
<li>禁止重复声明</li>
</ul>
<p>如果一个标识符已经在代码块内部被定义，那么在此代码块内使用同一个标识符进行 let 声明就会导致抛出错误。例如：</p>
<pre><code>var count = 30;
let count = 40; // Uncaught SyntaxError: Identifier &#39;count&#39; has already been declared
</code></pre>
<p>在例子中， count 变量被声明了两次：一次使用 var ，另一次使用 let 。因为 let 不能在同一作用域内重复声明一个已有标识符，此处的 let 声明就会抛出错误。但如果在嵌套的作用域内使用 let 声明一个同名的新变量，则不会抛出错误。</p>
<pre><code>var count = 30;
// 不会抛出错误
if (condition) &#123;
let count = 40;
// 其他代码
&#125;
</code></pre>
<ul>
<li>循环中的绑定块作用域的妙用</li>
</ul>
<p>开发者可能最希望实现for循环的块级作用域了，因为可以把声明的计数器变量限制在循环内，例如：</p>
<pre><code>for (let i = 0; i &lt; 10; i++) &#123;
// ...
&#125;
console.log(i);
// ReferenceError: i is not defined
</code></pre>
<p>上面代码中，计数器i只在for循环体内有效，在循环体外引用就会报错。</p>
<pre><code>var a = [];
for (var i = 0; i &lt; 10; i++) &#123;
a[i] = function () &#123;
    console.log(i);
&#125;;
&#125;
a[6](); // 10
</code></pre>
<p>上面代码中，变量i是var命令声明的，在全局范围内都有效，所以全局只有一个变量i。每一次循环，变量i的值都会发生改变，而循环内被赋给数组a的函数内部的console.log(i)，里面的i指向的就是全局的i。也就是说，所有数组a的成员里面的i，指向的都是同一个i，导致运行时输出的是最后一轮的i的值，也就是 10。</p>
<p>如果使用let，声明的变量仅在块级作用域内有效，最后输出的是 6。</p>
<pre><code>var a = [];
for (let i = 0; i &lt; 10; i++) &#123;
a[i] = function () &#123;
    console.log(i);
&#125;;
&#125;
a[6](); // 6
</code></pre>
<p>上面代码中，变量i是let声明的，当前的i只在本轮循环有效，所以每一次循环的i其实都是一个新的变量，所以最后输出的是6。你可能会问，如果每一轮循环的变量i都是重新声明的，那它怎么知道上一轮循环的值，从而计算出本轮循环的值？这是因为 JavaScript 引擎内部会记住上一轮循环的值，初始化本轮的变量i时，就在上一轮循环的基础上进行计算。</p>
<p>另外，for循环还有一个特别之处，就是设置循环变量的那部分是一个父作用域，而循环体内部是一个单独的子作用域。</p>
<pre><code>for (let i = 0; i &lt; 3; i++) &#123;
let i = &#39;abc&#39;;
console.log(i);
&#125;
// abc
// abc
// abc
</code></pre>
<h2 id="作用域链"><a href="#作用域链" class="headerlink" title="作用域链"></a>作用域链</h2><h3 id="什么是自由变量"><a href="#什么是自由变量" class="headerlink" title="什么是自由变量"></a>什么是自由变量</h3><p>首先认识一下什么叫做 <strong>自由变量</strong> 。如下代码中，console.log(a)要得到a变量，但是在当前的作用域中没有定义a（可对比一下b）。当前作用域没有定义的变量，这成为 自由变量 。自由变量的值如何得到 —— 向父级作用域寻找（这种说法并不严谨）。</p>
<pre><code>var a = 100
function fn() &#123;
    var b = 200
    console.log(a) // 这里的a在这里就是一个自由变量
    console.log(b)
&#125;
fn()
</code></pre>
<h3 id="什么是作用域链"><a href="#什么是作用域链" class="headerlink" title="什么是作用域链"></a>什么是作用域链</h3><p>如果父级也没呢？再一层一层向上寻找，直到找到全局作用域还是没找到，就宣布放弃。这种一层一层的关系，就是 作用域链 。</p>
<pre><code>var a = 100
function F1() &#123;
    var b = 200
    function F2() &#123;
        var c = 300
        console.log(a) // 自由变量，顺作用域链向父作用域找
        console.log(b) // 自由变量，顺作用域链向父作用域找
        console.log(c) // 本作用域的变量
    &#125;
    F2()
&#125;
F1()
</code></pre>
<h3 id="关于自由变量的取值"><a href="#关于自由变量的取值" class="headerlink" title="关于自由变量的取值"></a>关于自由变量的取值</h3><p>关于自由变量的值，上文提到要到父作用域中取，其实有时候这种解释会产生歧义。</p>
<pre><code>var x = 10
function fn() &#123;
console.log(x)
&#125;
function show(f) &#123;
var x = 20
(function() &#123;
    f() //10，而不是20
&#125;)()
&#125;
show(fn)
</code></pre>
<p>在fn函数中，取自由变量x的值时，要到哪个作用域中取？——要到创建fn函数的那个作用域中取，<strong>无论fn函数将在哪里调用</strong>。</p>
<p>所以相比而言，用这句话描述会更加贴切:<strong>要到创建这个函数的那个域”。作用域中取值</strong>,这里强调的是“创建”，而不是“调用”，其实这就是所谓的”静态作用域”</p>
<pre><code>var a = 10
function fn() &#123;
var b = 20
function bar() &#123;
    console.log(a + b) //30
&#125;
return bar
&#125;
var x = fn(),
b = 200
x() //bar()
</code></pre>
<p>fn()返回的是bar函数，赋值给x。执行x()，即执行bar函数代码。取b的值时，直接在fn作用域取出。取a的值时，试图在fn作用域取，但是取不到，只能转向创建fn的那个作用域中去查找，结果找到了,所以最后的结果是30</p>
<h2 id="作用域与执行上下文"><a href="#作用域与执行上下文" class="headerlink" title="作用域与执行上下文"></a>作用域与执行上下文</h2><p>作用域和执行上下文并不是相同的概念。</p>
<p>JavaScript属于解释型语言，JavaScript的执行分为：解释和执行两个阶段,这两个阶段所做的事并不一样：</p>
<h3 id="解释阶段："><a href="#解释阶段：" class="headerlink" title="解释阶段："></a>解释阶段：</h3><ul>
<li>词法分析</li>
<li>语法分析</li>
<li>作用域规则确定</li>
</ul>
<h3 id="执行阶段："><a href="#执行阶段：" class="headerlink" title="执行阶段："></a>执行阶段：</h3><ul>
<li>创建执行上下文</li>
<li>执行函数代码</li>
<li>垃圾回收</li>
</ul>
<p>JavaScript解释阶段就会确定作用域规则，所以作用域在函数定义时就已经确定了，而不是在函数调用时确定，但是执行上下文是函数执行之前创建的。执行上下文最明显的就是this的指向是执行时确定的。而作用域访问的变量是编写代码的结构确定的。</p>
<p>作用域和执行上下文之间最大的区别是：<br><strong>执行上下文在运行时确定，随时可能改变；作用域在定义时就确定，并且不会改变。</strong></p>
<p>一个作用域下可能包含若干个上下文环境。有可能从来没有过上下文环境（函数从来就没有被调用过）；有可能有过，现在函数被调用完毕后，上下文环境被销毁了；有可能同时存在一个或多个（闭包）。<strong>同一个作用域下，不同的调用会产生不同的执行上下文环境，继而产生不同的变量的值。</strong></p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="https://gitee.com/dmf-c/blog">dmf</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://gitee.com/dmf-c/blog/2021/07/10/js_file/ScopeChain/">https://gitee.com/dmf-c/blog/2021/07/10/js_file/ScopeChain/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://gitee.com/dmf-c/blog" target="_blank">dmf的个人博客</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"></div><div class="post_share"><div class="social-share" data-image="https://img1.baidu.com/it/u=3691791879,443411760&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=500&amp;h=889" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/blog/2021/07/31/js_file/ShallowDeep/"><img class="prev-cover" src="https://img1.baidu.com/it/u=3691791879,443411760&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=500&amp;h=889" onerror="onerror=null;src='/blog/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">浅拷贝与深拷贝</div></div></a></div><div class="next-post pull-right"><a href="/blog/2021/06/27/js_file/changeType/"><img class="next-cover" src="https://img1.baidu.com/it/u=3691791879,443411760&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=500&amp;h=889" onerror="onerror=null;src='/blog/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">JavaScript数据类型转换</div></div></a></div></nav></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">dmf</div><div class="author-info__description"></div></div><div class="card-info-data site-data is-center"><a href="/blog/archives/"><div class="headline">文章</div><div class="length-num">27</div></a><a href="/blog/tags/"><div class="headline">标签</div><div class="length-num">0</div></a><a href="/blog/categories/"><div class="headline">分类</div><div class="length-num">6</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/xxxxxx"><i class="fab fa-github"></i><span>Follow Me</span></a></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">业精于勤，荒于嬉。</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8%E5%9F%9F-Scope"><span class="toc-number">1.</span> <span class="toc-text">作用域(Scope)</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="toc-number">1.1.</span> <span class="toc-text">什么是作用域</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%A8%E5%B1%80%E4%BD%9C%E7%94%A8%E5%9F%9F%E5%92%8C%E5%87%BD%E6%95%B0%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="toc-number">1.2.</span> <span class="toc-text">全局作用域和函数作用域</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9D%97%E7%BA%A7%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="toc-number">1.3.</span> <span class="toc-text">块级作用域</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8%E5%9F%9F%E9%93%BE"><span class="toc-number">2.</span> <span class="toc-text">作用域链</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E8%87%AA%E7%94%B1%E5%8F%98%E9%87%8F"><span class="toc-number">2.1.</span> <span class="toc-text">什么是自由变量</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E4%BD%9C%E7%94%A8%E5%9F%9F%E9%93%BE"><span class="toc-number">2.2.</span> <span class="toc-text">什么是作用域链</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B3%E4%BA%8E%E8%87%AA%E7%94%B1%E5%8F%98%E9%87%8F%E7%9A%84%E5%8F%96%E5%80%BC"><span class="toc-number">2.3.</span> <span class="toc-text">关于自由变量的取值</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8%E5%9F%9F%E4%B8%8E%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87"><span class="toc-number">3.</span> <span class="toc-text">作用域与执行上下文</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A7%A3%E9%87%8A%E9%98%B6%E6%AE%B5%EF%BC%9A"><span class="toc-number">3.1.</span> <span class="toc-text">解释阶段：</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%89%A7%E8%A1%8C%E9%98%B6%E6%AE%B5%EF%BC%9A"><span class="toc-number">3.2.</span> <span class="toc-text">执行阶段：</span></a></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/blog/2023/01/08/vue_file/vuenote/" title="vue3入门笔记"><img src="https://img1.baidu.com/it/u=1828439677,2166285235&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=400&amp;h=300" onerror="this.onerror=null;this.src='/blog/img/404.jpg'" alt="vue3入门笔记"/></a><div class="content"><a class="title" href="/blog/2023/01/08/vue_file/vuenote/" title="vue3入门笔记">vue3入门笔记</a><time datetime="2023-01-07T16:00:00.000Z" title="发表于 2023-01-08 00:00:00">2023-01-08</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2022/02/20/vue_file/comm/" title="vue组件间通信六种方式"><img src="https://img1.baidu.com/it/u=1828439677,2166285235&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=400&amp;h=300" onerror="this.onerror=null;this.src='/blog/img/404.jpg'" alt="vue组件间通信六种方式"/></a><div class="content"><a class="title" href="/blog/2022/02/20/vue_file/comm/" title="vue组件间通信六种方式">vue组件间通信六种方式</a><time datetime="2022-02-19T16:00:00.000Z" title="发表于 2022-02-20 00:00:00">2022-02-20</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2022/02/05/wxEcharts/" title="微信小程序使用 echarts"><img src="https://img1.baidu.com/it/u=1828439677,2166285235&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=400&amp;h=300" onerror="this.onerror=null;this.src='/blog/img/404.jpg'" alt="微信小程序使用 echarts"/></a><div class="content"><a class="title" href="/blog/2022/02/05/wxEcharts/" title="微信小程序使用 echarts">微信小程序使用 echarts</a><time datetime="2022-02-04T16:00:00.000Z" title="发表于 2022-02-05 00:00:00">2022-02-05</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2022/01/30/vue_file/vue_router/" title="vue-router学习"><img src="https://img1.baidu.com/it/u=1828439677,2166285235&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=400&amp;h=300" onerror="this.onerror=null;this.src='/blog/img/404.jpg'" alt="vue-router学习"/></a><div class="content"><a class="title" href="/blog/2022/01/30/vue_file/vue_router/" title="vue-router学习">vue-router学习</a><time datetime="2022-01-29T16:00:00.000Z" title="发表于 2022-01-30 00:00:00">2022-01-30</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2022/01/16/vue_file/vuex/" title="Vuex使用方法"><img src="https://img1.baidu.com/it/u=1828439677,2166285235&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=400&amp;h=300" onerror="this.onerror=null;this.src='/blog/img/404.jpg'" alt="Vuex使用方法"/></a><div class="content"><a class="title" href="/blog/2022/01/16/vue_file/vuex/" title="Vuex使用方法">Vuex使用方法</a><time datetime="2022-01-15T16:00:00.000Z" title="发表于 2022-01-16 00:00:00">2022-01-16</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2023 By dmf</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/blog/js/utils.js"></script><script src="/blog/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.min.js"></script><div class="js-pjax"></div><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>